/*
	Copyright (C) 2010 Tim Beyer
	
    This file is part of Pixelbots.

    Pixelbots is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Pixelbots is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Pixelbots.  If not, see <http://www.gnu.org/licenses/>.
	
*/


/************************************************
 *						*
 * 	Objects					*
 *						*
 ************************************************/
 
 
 /* 
  * A simple RGBa pixel
  */
function Pixel(r,g,b,a){

    this.r=r;
    this.g=g;
    this.b=b;
    this.a=a;
    
    this.grayScale = function(){
		var brightness=this.getBrightness();
        this.r = brightness;
        this.g = brightness;
        this.b = brightness;
    }
    
    this.invert = function(){
		this.r = 255 - r;
		this.g = 255 - g;
		this.b = 255 - b;    
    }
    
    this.getBrightness = function(){
		return (this.r+this.g+this.b)/3;
    }
    
    this.getRelativeBrightness = function(){
		return ((100/255)*this.getBrightness())/100;
    }

}

/*
 * PixelImage contains a reference to the image data
 * and some methods to put and get pixels
 */

function PixelImage(width,height){

	this.width = width;
	this.height = height;

	var imageData = createEmptyImgData(width,height);
	
	this.getPixel = function(x,y){
	    return getPixel(imageData,x,y);
	}
	
	this.putPixel = function(pixel,x,y){
	    putPixel(imageData,pixel,x,y);
	}
	
	this.grayScale = function(){
	   this.applyPixelFunction(
		function(pixel){
			pixel.grayScale()
		}    
	    );
	}
	
	this.invert = function(){
	   this.applyPixelFunction(
		function(pixel){
			pixel.invert()
		}    
	    );
	}
	
	/**
	 * Takes as argument a function that takes a pixel as argument
	 * Then loops over the image data and calls this function with each pixel in the image
	 */
	this.applyPixelFunction = function(funct){
	    for (x=0; x<imageData.width; x++)
		{
		    for (y=0; y<imageData.height; y++)
		    {
		    	var pixel = this.getPixel(x,y);
			funct(pixel);    
			this.putPixel(pixel,x,y);
		    }
		}
	}
	
	this.drawToCanvas = function(context,x,y){
	    context.putImageData(imageData,0,0);
	}
	
	this.toPNG = function(){
	    //create new empty canvas
	    //its only purpose is to hold the image to be saved 
	    var canvas=document.createElement("canvas");
	    var context=canvas.getContext("2d");
	    canvas.width = this.width;
	    canvas.height = this.height;
	    this.drawToCanvas(context,x,y);
	    
	    return canvas.toDataURL();
	}
	
	this.loadImage = function(image){
	    imageData = getImageData(image);
	    this.width = imageData.width;
	    this.height = imageData.height;
	
	}
	
	function createEmptyImgData(width,height){

		var canvas=document.createElement("canvas");
		var context=canvas.getContext("2d");

		canvas.width = width;
		canvas.height = height;
		
		//fill with black
		context.fillStyle = "rgb(0,0,0)";
		context.fillRect (0, 0, width, height);
	  
		// Get the imageData from canvas
		var imgd = context.getImageData(0, 0, width, height);
		
		return imgd;
	
	}
	

}


/*
 * This is basically a grayscale image
 */
 
 function BrightnessMap(pixelImage){
 
	var map = new Array();
	this.width = pixelImage.width;
	this.height = pixelImage.height;
	
	//get brightness values
	for (y=0; y<this.height; y++)
	{
	    for (x=0; x<this.width; x++)
	    {
		map.push(pixelImage.getPixel(x,y).getBrightness());
	    }
	}
	
	function getIndex(x,y){
	    return (y*this.width + x);
	}
	
	this.getBrightness = function(x,y){
	    return map[getIndex(x,y)];
	}
	
	this.getRelativeBrightness = function(x,y){
	    return (100/255)*this.getBrightness(x,y)/100;
	}
 
 }

/************************************************
 *						*
 * 	Functions				*
 *						*
 ************************************************/

/*
 * Extracts the image data from an image 
 */

function getImageData(image){

		//create new empty canvas
		//its only purpose is to hold the image to be converted 
		var canvas=document.createElement("canvas");
		var context=canvas.getContext("2d");
  
		var width = image.width;
		var height = image.height;
		canvas.width = width;
		canvas.height = height;
		context.drawImage(image,0,0);
	  
		// Get the imageData from the given coordinates and dimensions.
		var imgd = context.getImageData(0, 0, width, height);
		
		return imgd;
 }


 
function getPixel(imageData,x,y){
    var startIndex = imgDataArrayIndex(imageData,x,y);
    var r = imageData.data[startIndex];
    var g = imageData.data[startIndex+1];
    var b = imageData.data[startIndex+2];
    var a = imageData.data[startIndex+3];
    
    return new Pixel(r,g,b,a);

}

function putPixel(imageData,pixel,x,y){
    var startIndex = imgDataArrayIndex(imageData,x,y);
    imageData.data[startIndex] = pixel.r;
    imageData.data[startIndex+1] = pixel.g;
    imageData.data[startIndex+2] = pixel.b;
    imageData.data[startIndex+3] = pixel.a;

}


//turns an x,y coordinate into the corresponding number, points at red pixel
function imgDataArrayIndex(imageData,x,y){
    return (y*(imageData.width*4)) + (x*4);
}
